import Dep from './Dep'

let uid = 0


function parsePath(str) {
  const segments = str.split('.')
  return (obj) => {
    for (let k of segments) {
      if (!obj) return;
      obj = obj[k]
    }
    return obj
  }
}

export default class Watcher {
  /**
   * @param {Object} target 需要监听的对象
   * @param {String} expression 对象的属性
   * @param {Function} callback 监听到变化后执行的逻辑
   */
  constructor (target, expression, callback) {
    this.id = uid++
    this.target = target
    this.callback = callback
    this.getter = parsePath(expression) // 返回一个函数，这个函数可以解析targe对象的expression
    this.value = this.get()  // target.expression 的值
  }

  update () {
    this.run()
  }

  /** 获得targe对象的expression的值  */
  get () {
    // 将这个Watcher实例存储到全局
    Dep.target = this

    let value;
    try {
      value = this.getter(this.target)
    } catch (error) {
      
    } finally {
      Dep.target = null
    }
    return value
  }

  run () {
    this.getAndInvoke(this.callback)
  }

  getAndInvoke (cb) {
    const value = this.get() // 可以理解为获取最新值
    if (value != this.value || typeof value != 'object') {
      const oldValue = this.value
      this.value = value
      cb.call(this.target, value, oldValue)
    }
  }
}
